package gold.digger;

import java.util.*;

/**
 * Created by fanzhenyu02 on 2020/6/27.
 * common problem solver template.
 */
public class LC341 {
    public long startExecuteTime = System.currentTimeMillis();


    /**
     * // This is the interface that allows for creating nested lists.
     * // You should not implement it, or speculate about its implementation
     * public interface NestedInteger {
     * <p>
     * // @return true if this NestedInteger holds a single integer, rather than a nested list.
     * public boolean isInteger();
     * <p>
     * // @return the single integer that this NestedInteger holds, if it holds a single integer
     * // Return null if this NestedInteger holds a nested list
     * public Integer getInteger();
     * <p>
     * // @return the nested list that this NestedInteger holds, if it holds a nested list
     * // Return null if this NestedInteger holds a single integer
     * public List<NestedInteger> getList();
     * }
     */

    public class NestedInteger {
        public boolean intFlag = true;
        public Object val;

        NestedInteger(boolean intFlag, Object val) {
            this.intFlag = intFlag;
            this.val = val;
        }

        public boolean isInteger() {
            return intFlag;
        }

        public Integer getInteger() {
            return ((Integer) val);
        }

        public List<NestedInteger> getList() {
            List<Integer> intRes = ((List<Integer>) val);
            List<NestedInteger> res = new ArrayList<>();
            for (Integer intRe : intRes) {
                res.add(new NestedInteger(true, intRe));
            }

            return res;
        }
    }


    public class NestedIterator implements Iterator<Integer> {

        public List<Integer> realList = new ArrayList<>();
        public int curElementIndex;

        public NestedIterator(List<NestedInteger> nestedList) {
            this.realList = getRealListRecur(nestedList);
            curElementIndex = 0;
        }

        public List<Integer> getRealListRecur(List<NestedInteger> nestedList) {
            if (null == nestedList || nestedList.size() <= 0) {
                return new ArrayList<>();
            }

            List<Integer> realList = new ArrayList<>();
            for (NestedInteger el : nestedList) {
                if (el.isInteger()) {
                    realList.add(el.getInteger());
                    continue;
                }

                List<Integer> elList = getRealListRecur(el.getList());
                if (null != elList && elList.size() >= 1) {
                    realList.addAll(elList);
                }
            }

            return realList;

        }

        @Override
        public Integer next() {
            return realList.get(curElementIndex++);
        }

        @Override
        public boolean hasNext() {
            return curElementIndex <= realList.size() - 1;
        }
    }

    /**
     * Your NestedIterator object will be instantiated and called as such:
     * NestedIterator i = new NestedIterator(nestedList);
     * while (i.hasNext()) v[f()] = i.next();
     */


    public void run() {
//     [[1,1],2,[1,1]]
        NestedInteger a = new NestedInteger(false, new ArrayList<Integer>(Arrays.asList(1, 1)));
        NestedInteger b = new NestedInteger(true, 2);
        NestedInteger c = new NestedInteger(false, new ArrayList<Integer>(Arrays.asList(1, 1)));
        List<NestedInteger> list = new ArrayList<>();
        list.add(a);
        list.add(b);
        list.add(c);

        NestedIterator it = new NestedIterator(new ArrayList<NestedInteger>());
        while (it.hasNext()) {
            System.out.println(it.next());
        }


    }

    public static void main(String[] args) throws Exception {
        LC341 an = new LC341();

        an.run();


        System.out.println("\nanswer total execute time: " + (System.currentTimeMillis() - an.startExecuteTime) + " ms.");
    }
}
